/**
 * 
 */
package edu.umd.clip.lm.tests;

import edu.berkeley.nlp.util.*;
import edu.umd.clip.lm.model.*;
import edu.umd.clip.lm.questions.*;
import edu.umd.clip.lm.util.*;
import edu.umd.clip.lm.util.tree.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class AnalyzeHFTQuestionDistances {
	public static class Options {
        @Option(name = "-config", required = true, usage = "XML config file")
		public String config;
        @Option(name = "-jobs", required = false, usage = "number of concurrent jobs (default: 1)")
        public int jobs = 1;
        @Option(name = "-forest", required = false, usage = "LM ID to train (default: " + LanguageModel.PRIMARY_LM_ID + ")")
		public String lm = LanguageModel.PRIMARY_LM_ID;        
	}

	
	private static void computeDistances(int offset, int[] distances, BinaryTree<HistoryTreePayload> tree, SimpleList<BinaryPrefix> prefixes) {
		Question q = tree.getPayload().question;
		if (q != null && q.getQuestionType() == Question.BINARY_PREFIX_QUESTION && q.isAboutHidden() && q.getTimeOffset() == offset) {
			BinaryPrefix prefix = ((BinaryPrefixQuestion) q).getPrefix();
			int minDistance = prefix.getSize();
			
			for(SimpleList<BinaryPrefix> tail = prefixes; tail != null; tail = tail.tail()) {
				BinaryPrefix p = tail.head();
				if (p == null) break;
				int distance = BinaryPrefix.distance(p, prefix);
				if (distance < minDistance) {
					minDistance = distance;
				}
			}
			
			prefixes = prefixes.add(prefix);
			distances[minDistance]++;
		}
		
		if (tree.getLeft() != null) {
			computeDistances(offset, distances, tree.getLeft(), prefixes);
		}

		if (tree.getRight() != null) {
			computeDistances(offset, distances, tree.getRight(), prefixes);
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
        OptionParser optParser = new OptionParser(Options.class);
        final Options opts = (Options) optParser.parse(args, true);

		Experiment.initialize(opts.config);
		final Experiment experiment = Experiment.getInstance();
		experiment.buildPrefixes();
		experiment.buildWordPrefixes();

		LanguageModel lm  = experiment.getLM(opts.lm);

		final BinaryTree<HistoryTreePayload> tree = lm.getHistoryTree();

		int[][] distances = new int[lm.getHiddenOrder()-1][];
		for(int i=0; i<distances.length; ++i) {
			distances[i] = new int[1000];
			computeDistances(-i-1, distances[i], tree, new SimpleList<BinaryPrefix>());
			
			int maxDistance = distances[i].length-1;
			while(maxDistance > 0 && distances[i][maxDistance] == 0) --maxDistance;
			
			System.out.printf("Offset: %d, max distance: %d\n", (-1-i), maxDistance);
			for(int j=0; j<=maxDistance; ++j) {
				System.out.printf("[%2d]: %d\n", j, distances[i][j]);
			}
			System.out.println();
		}
		
	}

}
